import Access from '@/components/Access';
import HandleBtn from '@/components/HandleBar/btn';
import type { ActionType, ProColumns, ProFormInstance } from '@/components/Pro/';
import {
  ModalForm,
  ProFormRadio,
  ProFormSelect,
  ProFormText,
  ProFormTextArea,
  ProTable,
} from '@/components/Pro/';
import {
  stationControllerAddStation as add,
  stationControllerBatch as batchHandle,
  stationControllerDownloadExcel as downloadFile,
  stationControllerEditStation as edit,
  stationControllerList as getList,
  stationControllerNextStationNo as getStationCode,
  stationControllerUploadExcel as uploadFile,
} from '@/services/ess/station';
import { sysTenantControllerSearch as getTenantList } from '@/services/ess/sysTenant';
import {
  DATABASE_TYPE_ENUM,
  fetchDictInfo,
  getGlobalHandleTip,
  GLOBAL_HANDLE_TIP_TYPE,
} from '@/utils';
import { downloadFetch } from '@/utils/downloadFile';
import type { UploadProps } from 'antd';
import { message, Modal, Select, Space, Switch, Upload } from 'antd';
import React, { useEffect, useRef, useState } from 'react';
import { Link, useAccess, useIntl, useModel } from 'umi';
import Styles from './index.less';

const { confirm } = Modal;

/**
 * @zh-CN 添加节点
 * @param fields
 */
const handleAdd = async (fields: API.StationReq) => {
  try {
    const res = await add({
      ...fields,
    });
    if (res.success) {
      getGlobalHandleTip(GLOBAL_HANDLE_TIP_TYPE.ADD);
      return true;
    }
    return false;
  } catch (error) {
    getGlobalHandleTip(GLOBAL_HANDLE_TIP_TYPE.ADD, {
      error: true,
    });
    return false;
  }
};

/**
 * @zh-CN 编辑节点
 * @param fields
 */
const handleEdit = async (fields: API.StationReq) => {
  try {
    const res = await edit({
      ...fields,
    });
    if (res.success) {
      getGlobalHandleTip(GLOBAL_HANDLE_TIP_TYPE.EDIT);
      return true;
    }
    return false;
  } catch (error) {
    getGlobalHandleTip(GLOBAL_HANDLE_TIP_TYPE.EDIT, {
      error: true,
    });
    return false;
  }
};

const TableList: React.FC = () => {
  const { initialState, setInitialState } = useModel('@@initialState');
  const [createModalOpen, handleModalOpen] = useState<boolean>(false);

  const actionRef = useRef<ActionType>();
  const formRef = useRef<ProFormInstance>();

  const [currentRow, setCurrentRow] = useState<API.StationInfo>({});
  const [selectedRowsState, setSelectedRows] = useState<API.StationInfo[]>([]);
  const [dataSource, setDataSource] = useState<API.StationInfo[]>([]);
  const [stationRunStatusOptions, setStationRunStatusOptions] = useState([]);
  const [disabled, setDisabled] = useState(false);
  const access = useAccess();
  const intl = useIntl();
  const isEnglish = intl.locale === 'en-US';

  useEffect(() => {
    fetchDictInfo(DATABASE_TYPE_ENUM.STATION_RUN_STATUS, true).then((res) => {
      setStationRunStatusOptions(res ?? []);
    });
  }, []);

  // 更新站点信息
  const updateStationInfo = () => {
    initialState?.updateStationInfo?.(initialState).then((infos) => {
      if (infos) {
        setInitialState((s) => ({
          ...s,
          ...infos,
        }));
      }
    });
  };

  // 改变站点状态后重置selectedRowsState数据
  useEffect(() => {
    if (!selectedRowsState.length) {
      return;
    }
    const newSelectedRows = selectedRowsState.map((row) => {
      const newRow = dataSource.find((item) => row.id === item.id);
      if (newRow) {
        return newRow;
      }
      return row;
    });
    setSelectedRows(newSelectedRows);
  }, [dataSource]);

  function handleBatch(type: string) {
    if (selectedRowsState.length < 1) {
      message.warning(intl.formatMessage({ id: 'global.leastOne' }));
      return;
    }

    if (type === 'DELETE' && selectedRowsState.findIndex((row) => row.status === 1) > -1) {
      message.error(intl.formatMessage({ id: 'systemManagement.neddTochange.plantDel' }));
      return;
    }

    if (disabled) return;
    setDisabled(true);

    confirm({
      title: intl.formatMessage({ id: 'systemManagement.supplementary.prompt' }),
      content:
        type === 'DELETE'
          ? intl.formatMessage({
              id: 'systemManagement.supplementary.dataCannotBeRestoredAfterDeletion',
            })
          : `${intl.formatMessage({ id: 'systemManagement.neddTochange.siteTenantChage1' })}${
              selectedRowsState.length
            }${intl.formatMessage({ id: 'systemManagement.neddTochange.siteTenantChage2' })}`,
      onOk: async () => {
        const res = await batchHandle({
          ids: selectedRowsState.map((row) => row.id),
          type,
        });
        if (res.success) {
          const handleType =
            (type === 'DELETE' && GLOBAL_HANDLE_TIP_TYPE.DEL) ||
            (type === 'OPEN' && GLOBAL_HANDLE_TIP_TYPE.ENABLE) ||
            (type === 'DISABLE' && GLOBAL_HANDLE_TIP_TYPE.DISABLED) ||
            undefined;
          getGlobalHandleTip(handleType);
          actionRef.current?.reloadAndRest?.();
          updateStationInfo();
        }
      },
      afterClose: () => {
        setDisabled(false);
      },
    });
  }

  const uploadProps: UploadProps = {
    name: 'file',
    multiple: true,
    showUploadList: false,
    customRequest: async (info) => {
      const form = new FormData();
      form.append('file', info.file);
      const res = await uploadFile(form, { ingoreErrorMsg: true });
      if (res?.success) {
        message.success(
          `${info.file.name} ${intl.formatMessage({
            id: 'systemManagement.neddTochange.fileImportSuccess',
          })}`,
        );
        actionRef?.current?.reloadAndRest?.();
        return;
      }
      const msg = res?.message;
      message.error(
        `${info.file.name} ${intl.formatMessage({
          id: 'systemManagement.neddTochange.fileImportFailed',
        })} ${msg ? ',' + msg : ''}`,
      );
    },
  };

  const fetchTenant = async (params) => {
    const result = await getTenantList(params);
    return (result.data || []).map((item) => {
      return {
        label: item.tenantName,
        value: Number(item.tenantId),
      };
    });
  };

  const transformValueEnum = (arr = []) => {
    const obj = {};
    arr.forEach((item) => {
      obj[item.value] = {
        text: item.label,
      };
    });
    return obj;
  };

  const columns: ProColumns<API.StationInfo>[] = [
    {
      title: intl.formatMessage({ id: 'systemManagement.generalProcedure.SN' }),
      dataIndex: 'pageIndex',
      hideInSearch: true,
    },
    {
      title: intl.formatMessage({ id: 'systemManagement.siteAdministrationMenu.tenantName' }),
      dataIndex: 'tenantId',
      request: fetchTenant,
      fieldProps: { showSearch: true },
      render: (_, record) => record.tenantName,
      width: 120,
    },
    {
      title: intl.formatMessage({ id: 'systemManagement.siteAdministrationMenu.plantName' }),
      dataIndex: 'stationName',
      hideInSearch: true,
      width: 140,
    },
    {
      title: intl.formatMessage({ id: 'systemManagement.siteAdministrationMenu.plantCode' }),
      dataIndex: 'stationNo',
      hideInSearch: true,
      width: 100,
    },
    {
      title: intl.formatMessage({ id: 'systemManagement.siteAdministrationMenu.workStatus' }),
      dataIndex: 'runStatus',
      valueType: 'select',
      width: 120,
      valueEnum: transformValueEnum(stationRunStatusOptions),
      render: (_, record) => (
        <Select
          showSearch={false}
          options={stationRunStatusOptions}
          style={{ width: 82, height: 30 }}
          className={Styles.selectRunStatus}
          value={record?.runStatus}
          onChange={(v, option) => {
            confirm({
              title: intl.formatMessage({ id: 'systemManagement.supplementary.prompt' }),
              content: `${intl.formatMessage({ id: 'siteManage.changeStatus' })}${option.label}？`,
              onOk: async () => {
                const status = await handleEdit({ ...record, runStatus: v } as API.StationReq);
                if (status) {
                  actionRef.current?.reloadAndRest?.();
                }
              },
            });
          }}
        />
      ),
    },
    {
      title: intl.formatMessage({
        id: 'systemManagement.siteAdministrationMenu.plantInformationNotTitle',
      }),
      dataIndex: 'station',
      fieldProps: {
        placeholder: intl.formatMessage({ id: 'systemManagement.requiredFields.siteNameOrCode' }),
      },
      hideInTable: true,
    },
    {
      title: intl.formatMessage({ id: 'systemManagement.siteAdministrationMenu.plantStatus' }),
      dataIndex: 'status',
      valueEnum: {
        1: {
          text: intl.formatMessage({ id: 'systemManagement.generalProcedure.enable' }),
          status: '1',
        },
        0: {
          text: intl.formatMessage({ id: 'systemManagement.generalProcedure.disable' }),
          status: '0',
        },
      },
      render: (_, record) => (
        <Switch
          checkedChildren={intl.formatMessage({ id: 'systemManagement.generalProcedure.enable' })}
          unCheckedChildren={intl.formatMessage({
            id: 'systemManagement.generalProcedure.disable',
          })}
          checked={Boolean(record.status)}
          onChange={(checked) => {
            confirm({
              title: intl.formatMessage({ id: 'systemManagement.supplementary.prompt' }),
              content: intl.formatMessage({
                id: 'systemManagement.supplementary.doYouWantToChangeTheEnabledStatusOfThisData',
              }),
              onOk: async () => {
                // const changeTableData = [...dataSource];
                // changeTableData.splice(index, 1, { ...record, status: checked ? 1 : 0 });
                // setDataSource(changeTableData);
                const res = await batchHandle({
                  ids: [record.id],
                  type: checked ? 'OPEN' : 'DISABLE',
                });
                if (res?.success) {
                  getGlobalHandleTip(GLOBAL_HANDLE_TIP_TYPE.ENABLE);
                  actionRef.current?.reloadAndRest?.();
                  updateStationInfo();
                }
              },
            });
          }}
        />
      ),
      width: 100,
      hideInTable: !access.can('sys:station:setStatus'),
      hideInSearch: !access.can('sys:station:setStatus'),
    },
    {
      title: intl.formatMessage({ id: 'systemManagement.siteAdministrationMenu.plantType' }),
      dataIndex: 'stationType',
      request: () => fetchDictInfo(DATABASE_TYPE_ENUM.SITE_TYPE),
      valueType: 'select',
      width: 100,
    },
    {
      title: intl.formatMessage({ id: 'systemManagement.siteAdministrationMenu.contactPhone' }),
      dataIndex: 'contactPhone',
      hideInSearch: true,
      width: 130,
    },
    {
      title: intl.formatMessage({ id: 'systemManagement.siteAdministrationMenu.contact' }),
      dataIndex: 'contactName',
      hideInSearch: true,
      width: 100,
    },
    {
      title: intl.formatMessage({ id: 'systemManagement.siteAdministrationMenu.contact' }),
      dataIndex: 'contact',
      fieldProps: {
        placeholder: intl.formatMessage({ id: 'systemManagement.requiredFields.contactPerson' }),
      },
      hideInTable: true,
    },
    {
      title: intl.formatMessage({ id: 'systemManagement.siteAdministrationMenu.creationtime' }),
      dataIndex: 'createTime',
      width: 120,
      render: (_, record) => record.createTime,
      valueType: 'dateRange',
      search: {
        transform: (value) => {
          return {
            startDate: value[0],
            endDate: value[1],
          };
        },
      },
    },
    {
      title: intl.formatMessage({ id: 'systemManagement.generalProcedure.operation' }),
      dataIndex: 'option',
      valueType: 'option',
      width: isEnglish ? 300 : 250,
      fixed: 'right',
      render: (_, record) => (
        <Space>
          <Access accessible={access['sys:station:edit']} key="edit">
            <a
              onClick={() => {
                handleModalOpen(true);
                setCurrentRow(record);
              }}
            >
              {intl.formatMessage({ id: 'systemManagement.generalProcedure.edit' })}
            </a>
          </Access>
          <Access accessible={access['sys:station:collectArchives']} key="archives">
            <Link to={`/system/site/archives?id=${record.id}`}>
              {intl.formatMessage({ id: 'systemManagement.siteAdministrationMenu.collection' })}
            </Link>
          </Access>
          <Access accessible={access['sys:station:serviceConf']} key="config">
            <Link to={`/system/site/config?id=${record.id}`}>
              {intl.formatMessage({ id: 'systemManagement.siteAdministrationMenu.service' })}
            </Link>
          </Access>
          <Access accessible={access['sys:station:paramConf']} key="param">
            <Link to={`/system/site/param?id=${record.id}`}>
              {intl.formatMessage({ id: 'systemManagement.siteAdministrationMenu.parameter' })}
            </Link>
          </Access>
          <Access accessible={access['sys:station:detail']} key="detail">
            <Link to={`/system/site/detail?id=${record.id}`}>
              {intl.formatMessage({ id: 'systemManagement.generalProcedure.detail' })}
            </Link>
          </Access>
          <Access accessible={access['sys:station:del']} key="del">
            <a
              onClick={() => {
                if (record.status === 1) {
                  message.error(
                    intl.formatMessage({ id: 'systemManagement.neddTochange.plantDel' }),
                  );
                  return;
                }

                if (disabled) return;
                setDisabled(true);

                confirm({
                  title: intl.formatMessage({ id: 'systemManagement.supplementary.prompt' }),
                  content: intl.formatMessage({
                    id: 'systemManagement.supplementary.dataCannotBeRestoredAfterDeletion',
                  }),
                  onOk: async () => {
                    const res = await batchHandle({
                      ids: [record.id],
                      type: 'DELETE',
                    });
                    if (res.success) {
                      message.success(
                        intl.formatMessage({ id: 'systemManagement.neddTochange.deleteSuccess' }),
                      );
                      actionRef.current?.reloadAndRest?.();
                      updateStationInfo();
                    }
                  },
                  afterClose: () => {
                    setDisabled(false);
                  },
                });
              }}
            >
              {intl.formatMessage({ id: 'systemManagement.generalProcedure.delete' })}
            </a>
          </Access>
        </Space>
      ),
    },
  ];

  return (
    <div>
      <ProTable<API.StationInfo, API.PageParams>
        headerTitle={intl.formatMessage({
          id: 'systemManagement.siteAdministrationMenu.plantManagement',
        })}
        actionRef={actionRef}
        formRef={formRef}
        rowKey="id"
        toolBarRender={() => [
          <Access perm="sys:station:add" key="add">
            <HandleBtn
              handleType="add"
              onClick={() => {
                setCurrentRow({});
                handleModalOpen(true);
              }}
            >
              {intl.formatMessage({ id: 'systemManagement.generalProcedure.new' })}
            </HandleBtn>
          </Access>,
          <Access perm="sys:station:import" key="import">
            <Upload {...uploadProps}>
              <HandleBtn handleType="import">
                {' '}
                {intl.formatMessage({ id: 'systemManagement.generalProcedure.import' })}
              </HandleBtn>
            </Upload>
          </Access>,
          <Access perm="sys:station:export" key="export">
            <HandleBtn
              handleType="export"
              onClick={() => downloadFetch(downloadFile, formRef?.current?.getFieldsFormatValue())}
            >
              {intl.formatMessage({ id: 'systemManagement.generalProcedure.export' })}
            </HandleBtn>
          </Access>,
          <Access perm="sys:station:setStatus" key="enable">
            <HandleBtn handleType="enable" onClick={() => handleBatch('OPEN')}>
              {intl.formatMessage({ id: 'systemManagement.generalProcedure.batchEnable' })}
            </HandleBtn>
          </Access>,
          <Access perm="sys:station:setStatus" key="disabled">
            <HandleBtn handleType="disabled" onClick={() => handleBatch('DISABLE')}>
              {intl.formatMessage({ id: 'systemManagement.generalProcedure.batchDisable' })}
            </HandleBtn>
          </Access>,
          <Access perm="sys:station:del" key="delete">
            <HandleBtn
              onClick={() => {
                handleBatch('DELETE');
              }}
              handleType="delete"
            >
              {intl.formatMessage({ id: 'systemManagement.generalProcedure.batchDelete' })}
            </HandleBtn>
          </Access>,
        ]}
        request={async (params) => {
          const result = await getList(params);
          setDataSource(result?.data?.records || []);
          return result;
        }}
        dataSource={dataSource}
        columns={columns}
        rowSelection={{
          onChange: (_, selectedRows) => {
            setSelectedRows(selectedRows);
          },
        }}
      />
      <ModalForm
        modalProps={{
          destroyOnClose: true,
        }}
        title={
          currentRow?.id
            ? intl.formatMessage({ id: 'systemManagement.siteAdministrationMenu.editPlant' })
            : intl.formatMessage({ id: 'systemManagement.siteAdministrationMenu.addPlant' })
        }
        initialValues={{
          ...currentRow,
          status: currentRow?.status ?? 1,
        }}
        // width="760px"
        // labelCol={{
        //   flex: `0 0 120px`,
        // }}
        style={{
          marginRight: 40,
        }}
        colProps={{ md: 12 }}
        open={createModalOpen}
        onOpenChange={handleModalOpen}
        request={
          !currentRow?.id &&
          (async () => {
            const res = await getStationCode();
            return { stationNo: res?.data };
          })
        }
        onFinish={async (value) => {
          const formData = value as API.StationReq;

          let success;
          if (currentRow?.id) {
            success = await handleEdit({ ...currentRow, ...formData } as API.StationReq);
          } else {
            success = await handleAdd({ ...formData, runStatus: 1 } as API.StationReq);
          }
          if (success) {
            handleModalOpen(false);
            if (actionRef.current) {
              actionRef.current?.reloadAndRest?.();
            }
            updateStationInfo();
          }
        }}
      >
        <ProFormSelect
          name="tenantId"
          label={intl.formatMessage({ id: 'systemManagement.siteAdministrationMenu.tenantName' })}
          fieldProps={{
            showSearch: true,
          }}
          request={fetchTenant}
          rules={[
            {
              required: true,
              message: intl.formatMessage({ id: 'systemManagement.neddTochange.siteTenant' }),
            },
          ]}
        />
        <ProFormSelect
          name="stationType"
          label={intl.formatMessage({ id: 'systemManagement.siteAdministrationMenu.plantType' })}
          request={() => fetchDictInfo(DATABASE_TYPE_ENUM.SITE_TYPE)}
          rules={[
            {
              required: true,
              message: intl.formatMessage({ id: 'systemManagement.neddTochange.siteType' }),
            },
          ]}
        />
        <ProFormText
          name="stationNo"
          label={intl.formatMessage({ id: 'systemManagement.siteAdministrationMenu.plantCode' })}
          rules={[
            {
              required: true,
              message: intl.formatMessage({ id: 'systemManagement.neddTochange.siteCode' }),
            },
          ]}
          fieldProps={{
            maxLength: 10,
          }}
        />
        <ProFormText
          name="stationName"
          label={intl.formatMessage({ id: 'systemManagement.siteAdministrationMenu.plantName' })}
          rules={[
            {
              required: true,
              message: intl.formatMessage({ id: 'systemManagement.neddTochange.sitName' }),
            },
          ]}
          fieldProps={{
            maxLength: 30,
          }}
        />
        <ProFormText
          name="contactName"
          label={intl.formatMessage({ id: 'systemManagement.siteAdministrationMenu.contact' })}
          rules={[
            {
              required: true,
              message: intl.formatMessage({ id: 'systemManagement.neddTochange.siteContact' }),
            },
          ]}
          fieldProps={{
            maxLength: 30,
          }}
        />
        <ProFormText
          name="contactPhone"
          label={intl.formatMessage({ id: 'systemManagement.siteAdministrationMenu.contactPhone' })}
          rules={[
            {
              required: true,
              message: intl.formatMessage({ id: 'systemManagement.neddTochange.siteNumber' }),
            },
          ]}
          fieldProps={{
            maxLength: 30,
          }}
        />
        <ProFormRadio.Group
          label={intl.formatMessage({ id: 'systemManagement.siteAdministrationMenu.plantStatus' })}
          name="status"
          options={[
            {
              label: intl.formatMessage({ id: 'systemManagement.generalProcedure.enable' }),
              value: 1,
            },
            {
              label: intl.formatMessage({ id: 'systemManagement.generalProcedure.disable' }),
              value: 0,
            },
          ]}
          rules={[
            {
              required: true,
              message: intl.formatMessage({ id: 'systemManagement.neddTochange.siteStatus' }),
            },
          ]}
        />
        <ProFormText name="address" hidden />
        <ProFormText name="point" hidden />
        <ProFormTextArea
          colProps={{ md: 24 }}
          label={intl.formatMessage({
            id: 'systemManagement.siteAdministrationMenu.remarksDescription',
          })}
          name="desc"
          fieldProps={{
            maxLength: 140,
          }}
        />
      </ModalForm>
    </div>
  );
};
export default TableList;
